package com.xwintop.xTransfer.sender.service.impl;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xwintop.xTransfer.common.MsgLogger;
import com.xwintop.xTransfer.common.model.LOGKEYS;
import com.xwintop.xTransfer.common.model.LOGVALUES;
import com.xwintop.xTransfer.common.model.Msg;
import com.xwintop.xTransfer.messaging.IMessage;
import com.xwintop.xTransfer.sender.bean.SenderConfig;
import com.xwintop.xTransfer.sender.bean.SenderConfigWeChat;
import com.xwintop.xTransfer.sender.service.Sender;
import com.xwintop.xTransfer.task.quartz.TaskQuartzJob;
import com.xwintop.xTransfer.util.ParseVariableCommon;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.enums.WxType;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.service.WxService;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @ClassName: SenderWeChatImpl
 * @Description: 微信消息发送器实现类
 * @author: xufeng
 * @date: 2021/9/18 23:16
 */

@Service("senderWeChat")
@Scope("prototype")
@Getter
@Setter
@Slf4j
public class SenderWeChatImpl implements Sender {
    private SenderConfigWeChat senderConfigWeChat;

    private WxService wxMpService = null;

    @Override
    public Boolean send(IMessage msg, Map params) throws Exception {
        if ("2".equals(senderConfigWeChat.getWeChatType())) {
            handleQYWechat(msg, params);
        } else {
            sendTemplateMsg(msg, params);
        }
        Msg msgLogInfo = new Msg(LOGVALUES.EVENT_MSG_SENDED, msg.getId(), null);
        msgLogInfo.put(LOGKEYS.CHANNEL_IN_TYPE, msg.getProperty(LOGKEYS.CHANNEL_IN_TYPE));
        msgLogInfo.put(LOGKEYS.CHANNEL_IN, msg.getProperty(LOGKEYS.CHANNEL_IN));
        msgLogInfo.put(LOGKEYS.CHANNEL_OUT_TYPE, LOGVALUES.CHANNEL_TYPE_WECHAT);
        msgLogInfo.put(LOGKEYS.CHANNEL_OUT, senderConfigWeChat.getAppId());
        msgLogInfo.put(LOGKEYS.MSG_TAG, msg.getFileName());
        msgLogInfo.put(LOGKEYS.MSG_LENGTH, ArrayUtils.getLength(msg.getMessage()));
        msgLogInfo.put(LOGKEYS.JOB_ID, params.get(TaskQuartzJob.JOBID));
        msgLogInfo.put(LOGKEYS.JOB_SEQ, params.get(TaskQuartzJob.JOBSEQ));
        msgLogInfo.put(LOGKEYS.RECEIVER_TYPE, msg.getProperty(LOGKEYS.RECEIVER_TYPE));
        msgLogInfo.put(LOGKEYS.RECEIVER_ID, msg.getProperty(LOGKEYS.RECEIVER_ID));
        MsgLogger.info(msgLogInfo.toMap());
        return true;
    }

    //发送模板消息
    private void sendTemplateMsg(IMessage msg, Map params) throws Exception {
        if (wxMpService == null) {
            wxMpService = new WxMpServiceImpl();
            WxMpDefaultConfigImpl wxMpConfigStorage = new WxMpDefaultConfigImpl();
            wxMpConfigStorage.setAppId(senderConfigWeChat.getAppId());
            wxMpConfigStorage.setSecret(senderConfigWeChat.getAppSecret());
            ((WxMpService) wxMpService).setWxMpConfigStorage(wxMpConfigStorage);
        }

        List<WxMpTemplateData> data = new ArrayList<>();
        for (Map.Entry<Object, Object> objectObjectEntry : msg.getProperties().entrySet()) {
            data.add(new WxMpTemplateData(String.valueOf(objectObjectEntry.getKey()), String.valueOf(objectObjectEntry.getValue())));
        }
        JSONArray jsonArray = JSONArray.parseArray(msg.getMessageByString());
        for (int i = 0; i < jsonArray.size(); i++) {
            data.add(jsonArray.getObject(i, WxMpTemplateData.class));
        }
        WxMpTemplateMessage wxMpTemplateMessage = new WxMpTemplateMessage();
        wxMpTemplateMessage.setToUser(ParseVariableCommon.parseVariable(senderConfigWeChat.getOpenId(), msg, params));
        wxMpTemplateMessage.setTemplateId(ParseVariableCommon.parseVariable(senderConfigWeChat.getTemplateCode(), msg, params));
        wxMpTemplateMessage.setData(data);
        if (StringUtils.isNotEmpty(senderConfigWeChat.getUrl())) {
            wxMpTemplateMessage.setUrl(senderConfigWeChat.getUrl());
        }
        //小程序appId不为空时，填充链接小程序相关代码
        if (!StringUtils.isEmpty(senderConfigWeChat.getMiniProgramAppId())) {
            WxMpTemplateMessage.MiniProgram miniProgram = new WxMpTemplateMessage.MiniProgram();
            miniProgram.setAppid(senderConfigWeChat.getMiniProgramAppId());
            miniProgram.setPagePath(senderConfigWeChat.getPagePath());
            miniProgram.setUsePath(false);
            wxMpTemplateMessage.setMiniProgram(miniProgram);
        }

        String responseContent = wxMpService.post(senderConfigWeChat.getUrl(), wxMpTemplateMessage.toJson());
        JSONObject jsonObject = JSON.parseObject(responseContent);
        if (jsonObject.getIntValue("errcode") == 0) {
            log.info(senderConfigWeChat.getId() + " 发送成功：" + jsonObject.getString("msgid"));
        } else {
            throw new WxErrorException(WxError.fromJson(responseContent, WxType.MP));
        }
    }

    //发送企业微信消息
    private void handleQYWechat(IMessage msg, Map params) throws Exception {
        if (wxMpService == null) {
            wxMpService = new WxCpServiceImpl();
            WxCpConfigStorage wxCpConfigStorage = new WxCpDefaultConfigImpl();
            ((WxCpService) wxMpService).setWxCpConfigStorage(wxCpConfigStorage);
        }
        if (StringUtils.isNotEmpty(senderConfigWeChat.getTokenUrl())) {
            String accessToken = JSON.parseObject(HttpUtil.get(senderConfigWeChat.getTokenUrl())).getString("access_token");
            WxCpDefaultConfigImpl wxMpConfigStorage = new WxCpDefaultConfigImpl();
            if (!StringUtils.isEmpty(accessToken)) {
                wxMpConfigStorage.setAccessToken(accessToken);
                wxMpConfigStorage.setExpiresTime(System.currentTimeMillis() + 60 * 1000L);
            }
            wxMpConfigStorage.setCorpId(senderConfigWeChat.getAppId());
            wxMpConfigStorage.setCorpSecret(senderConfigWeChat.getAppSecret());
            ((WxCpService) wxMpService).setWxCpConfigStorage(wxMpConfigStorage);
        }
        WxCpMessage wxCpMessage = new WxCpMessage();
        wxCpMessage.setToUser(ParseVariableCommon.parseVariable(senderConfigWeChat.getOpenId(), msg, params));
        wxCpMessage.setAgentId(senderConfigWeChat.getAgentId());
        wxCpMessage.setContent(msg.getMessageByString());
        wxCpMessage.setMsgType("text");
        wxMpService.post(senderConfigWeChat.getUrl(), wxCpMessage.toJson());
        String responseContent = wxMpService.post(senderConfigWeChat.getUrl(), wxCpMessage.toJson());
        JSONObject jsonObject = JSON.parseObject(responseContent);
        if (jsonObject.getInteger("errcode") == 0) {
            log.info(senderConfigWeChat.getId() + " 企业微信发送成功");
        } else {
            throw new WxErrorException(WxError.fromJson(responseContent, WxType.CP));
        }
    }

    @Override
    public void setSenderConfig(SenderConfig senderConfig) throws Exception {
        this.senderConfigWeChat = (SenderConfigWeChat) senderConfig;
    }

    @Override
    public void destroy() throws Exception {
        if (wxMpService != null) {
            wxMpService = null;
        }
    }
}
